<template>
  <div class="schedule-calendar">
    <h2>排班日历</h2>
    <button class="save-button" @click="saveSchedule">保存排班</button>
    <button class="stats-button" @click="toggleStats">查看统计</button>
    <button v-if="showStats" class="chart-type-button" @click="changeChartType(chartType === 'bar' ? 'pie' : 'bar')">
      {{ chartType === 'bar' ? '切换饼图' : '切换柱状图' }}
    </button>
    <button v-if="showStats" class="export-button" @click="exportChartData">导出数据</button>
    <div class="employee-filter">
      <label for="employeeFilter">筛选员工: </label>
      <select id="employeeFilter" v-model="selectedEmployee">
        <option value="">全部员工</option>
        <option v-for="employee in employeeList" :key="employee.id" :value="employee.id">
          {{ employee.name }}
        </option>
      </select>
    </div>
    
    <div class="chart-container" v-if="showStats">
      <canvas id="statsChart"></canvas>
    </div>
    <div class="calendar-container">
      <div class="calendar-header">
        <button @click="prevMonth">上个月</button>
        <span class="month-title">{{ currentMonth }}</span>
        <button @click="nextMonth">下个月</button>
      </div>
      <div class="calendar-grid">
        <div class="calendar-row" v-for="week in calendarWeeks" :key="week[0].date">
          <div 
            class="calendar-day" 
            v-for="day in week" 
            :key="day.date" 
            :class="{
              'special-day': day.isSpecialDay,
              'weekend': day.fullDate.getDay() === 0 || day.fullDate.getDay() === 6,
              'holiday': this.holidays.some(h => h.date === day.fullDate.toISOString().split('T')[0])
            }">
            <div class="day-header">{{ day.date }}</div>
            <div class="shifts-container">
              <div 
                class="shift-item" 
                v-for="shift in day.shifts" 
                :key="shift.id"
                :class="{ 'conflict-shift': shift.isConflict }"
                @mouseover="showEmployeeTooltip(shift.employeeId, $event)"
                @mouseleave="hideEmployeeTooltip"
                draggable="true"
                @dragstart="handleDragStart($event, shift)">
                {{ shift.employeeName }}: {{ shift.startTime }} - {{ shift.endTime }}
              </div>
              <div class="employee-tooltip" v-if="tooltip.visible" :style="{ top: tooltip.y + 'px', left: tooltip.x + 'px' }">
                <h4>{{ tooltip.employeeName }}</h4>
                <p>本月排班: {{ tooltip.totalShifts }} 次</p>
                <p>总工时: {{ tooltip.totalHours }} 小时</p>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import Chart from 'chart.js/auto';

export default {
  name: 'ScheduleCalendar',
  props: {
    scheduleData: {
      type: Object,
      required: true
    },
    holidays: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {      currentDate: new Date(),
      selectedEmployee: '',      employeeList: [],
      conflictShifts: [],
      showStats: false,
      chartType: 'bar',
      statsData: {
        labels: [],
        shiftsCount: [],
        hoursCount: []
      },
      tooltip: {
        visible: false,
        x: 0,
        y: 0,
        employeeId: '',
        employeeName: '',
        totalShifts: 0,
        totalHours: 0
      },
      dragState: {
        active: false,
        valid: false
      },
      chart: null
    }
  },
  computed: {
    currentMonth() {
      return this.currentDate.toLocaleString('default', { month: 'long', year: 'numeric' })
    },
    calendarWeeks() {
      // 生成日历周数据
      const weeks = []
      const firstDay = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth(), 1)
      const lastDay = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 0)
      
      let currentDay = new Date(firstDay)
      currentDay.setDate(currentDay.getDate() - currentDay.getDay())
      
      while (currentDay <= lastDay || weeks.length < 6) {
        const week = []
        for (let i = 0; i < 7; i++) {
          const dayDate = new Date(currentDay)
          const isSpecialDay = this.isSpecialDay(dayDate)
          const shifts = this.getShiftsForDay(dayDate)
          
          week.push({
            date: dayDate.getDate(),
            fullDate: dayDate,
            isSpecialDay,
            shifts
          })
          
          currentDay.setDate(currentDay.getDate() + 1)
        }
        weeks.push(week)
      }
      
      return weeks
    }
  },
  methods: {
    async saveSchedule() {
      try {
        const response = await fetch('/api/schedule/save', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json'
          },
          body: JSON.stringify(this.scheduleData)
        });
        
        if (!response.ok) {
          throw new Error('保存失败');
        }
        
        alert('排班保存成功');
      } catch (error) {
        console.error('保存排班时出错:', error);
        alert('保存排班时出错: ' + error.message);
      }
    },
    prevMonth() {
      this.currentDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() - 1, 1)
    },
    nextMonth() {
      this.currentDate = new Date(this.currentDate.getFullYear(), this.currentDate.getMonth() + 1, 1)
    },
    isSpecialDay(date) {
      // 检查是否是周末或节假日
      const isWeekend = date.getDay() === 0 || date.getDay() === 6;
      const isHoliday = this.holidays.some(h => h.date === date.toISOString().split('T')[0]);
      
      return isWeekend || isHoliday;
    },
    
    checkShiftConflicts(shifts) {
      // 检查班次冲突
      const conflicts = [];
      const conflictDetails = [];
      
      for (let i = 0; i < shifts.length; i++) {
        for (let j = i + 1; j < shifts.length; j++) {
          if (shifts[i].startTime < shifts[j].endTime && shifts[i].endTime > shifts[j].startTime) {
            conflicts.push(shifts[i].id);
            conflicts.push(shifts[j].id);
            conflictDetails.push({
              shift1: shifts[i].id,
              shift2: shifts[j].id,
              employee1: shifts[i].employeeName,
              employee2: shifts[j].employeeName,
              time: `${shifts[i].startTime}-${shifts[i].endTime} 与 ${shifts[j].startTime}-${shifts[j].endTime}`
            });
          }
        }
      }
      
      // 发送冲突详情给父组件
      if (conflictDetails.length > 0) {
        this.$emit('conflict-detected', conflictDetails);
      }
      
      return conflicts;
    },
    getShiftsForDay(date) {
      // 获取某天的所有班次
      const dateStr = date.toISOString().split('T')[0]
      const shifts = []
      
      for (const [employeeId, employeeShifts] of Object.entries(this.scheduleData)) {
        // 如果选择了特定员工，只显示该员工的班次
        if (this.selectedEmployee && this.selectedEmployee !== employeeId) continue;
        
        for (const shift of employeeShifts) {
          if (shift.date === dateStr) {
            shifts.push({
              ...shift,
              employeeName: this.getEmployeeName(employeeId),
              employeeId: employeeId
            })
          }
        }
      }
      
      // 检查班次冲突
      const conflictIds = this.checkShiftConflicts(shifts);
      this.conflictShifts = conflictIds;
      
      return shifts.map(shift => ({
        ...shift,
        isConflict: conflictIds.includes(shift.id)
      }));
    },
    getEmployeeName(employeeId) {
      // 根据员工ID获取员工姓名
      return `员工${employeeId}` // 实际项目中应从员工服务获取
    },
    
    showEmployeeTooltip(employeeId, event) {
      const employeeShifts = this.scheduleData[employeeId] || [];
      const currentMonth = this.currentDate.getMonth();
      
      // 计算本月排班次数和总工时
      const monthShifts = employeeShifts.filter(shift => {
        const shiftDate = new Date(shift.date);
        return shiftDate.getMonth() === currentMonth;
      });
      
      const totalHours = monthShifts.reduce((sum, shift) => {
        const start = new Date(`2000-01-01T${shift.startTime}`);
        const end = new Date(`2000-01-01T${shift.endTime}`);
        return sum + (end - start) / (1000 * 60 * 60);
      }, 0);
      
      this.tooltip = {
        visible: true,
        x: event.clientX + 10,
        y: event.clientY + 10,
        employeeId,
        employeeName: this.getEmployeeName(employeeId),
        totalShifts: monthShifts.length,
        totalHours: totalHours.toFixed(1)
      };
    },
    
    hideEmployeeTooltip() {
      this.tooltip.visible = false;
    },
    
    handleDragStart(event, shift) {
      this.dragState.active = true;
      event.dataTransfer.setData('text/plain', JSON.stringify(shift));
      event.target.classList.add('dragging');
    },
    
    handleDragEnd() {
      this.dragState.active = false;
      document.querySelectorAll('.dragging').forEach(el => {
        el.classList.remove('dragging');
      });
      document.querySelectorAll('.drag-valid, .drag-invalid').forEach(el => {
        el.classList.remove('drag-valid', 'drag-invalid');
      });
    },
    
    handleDragOver(event, day) {
      event.preventDefault();
      event.dataTransfer.dropEffect = 'move';
      
      const isValid = this.validateDragOperation(
        JSON.parse(event.dataTransfer.getData('text/plain')),
        day.fullDate.toISOString().split('T')[0]
      );
      
      this.dragState.valid = isValid;
      event.target.classList.add(isValid ? 'drag-valid' : 'drag-invalid');
    },
    
    handleDragLeave(event) {
      event.target.classList.remove('drag-valid', 'drag-invalid');
    },
    
    handleDrop(event, day) {
      event.preventDefault();
      const shiftData = JSON.parse(event.dataTransfer.getData('text/plain'));
      const targetDate = day.fullDate.toISOString().split('T')[0];
      
      // 验证拖拽操作是否有效
      if (!this.validateDragOperation(shiftData, targetDate)) {
        return;
      }
      
      // 更新班次日期
      const updatedShift = {
        ...shiftData,
        date: targetDate
      };
      
      // 从原位置移除班次
      const employeeShifts = this.scheduleData[shiftData.employeeId];
      const index = employeeShifts.findIndex(s => s.id === shiftData.id);
      if (index !== -1) {
        employeeShifts.splice(index, 1);
      }
      
      // 添加到新位置
      if (!this.scheduleData[shiftData.employeeId]) {
        this.$set(this.scheduleData, shiftData.employeeId, []);
      }
      this.scheduleData[shiftData.employeeId].push(updatedShift);
      
      // 检查冲突并更新
      this.checkShiftConflicts(this.getShiftsForDay(day.fullDate));
      
      // 触发重新渲染
      this.$forceUpdate();
      
      // 调用API保存更改
      this.saveSchedule();
    },
    
    validateDragOperation(shiftData, targetDate) {
      // 验证员工是否允许在该日期工作
      if (this.isSpecialDay(new Date(targetDate))) {
        this.$emit('show-toast', { type: 'error', message: '特殊日期不允许排班' });
        return false;
      }
      
      // 验证员工是否已有班次冲突
      const existingShifts = this.scheduleData[shiftData.employeeId] || [];
      const newShift = {
        ...shiftData,
        date: targetDate
      };
      
      const conflicts = this.checkShiftConflicts([...existingShifts, newShift]);
      if (conflicts.includes(newShift.id)) {
        this.$emit('show-toast', { 
          type: 'error', 
          message: '该员工在此时间段已有其他班次安排',
          details: conflicts.length > 1 ? '发现多个冲突班次' : ''
        });
        return false;
      }
      
      // 实时高亮显示冲突
      this.$emit('highlight-conflicts', conflicts);
      return true;
    },
    
    toggleStats() {
      this.showStats = !this.showStats;
      if (this.showStats) {
        this.$nextTick(() => {
          this.generateStatsChart();
        });
      } else if (this.chart) {
        this.chart.destroy();
        this.chart = null;
      }
    },
    
    generateStatsChart() {
      const ctx = document.getElementById('statsChart');
      
      // 准备统计数据
      this.statsData.labels = [];
      this.statsData.shiftsCount = [];
      this.statsData.hoursCount = [];
      
      const currentMonth = this.currentDate.getMonth();
      
      for (const [employeeId, employeeShifts] of Object.entries(this.scheduleData)) {
        const monthShifts = employeeShifts.filter(shift => {
          const shiftDate = new Date(shift.date);
          return shiftDate.getMonth() === currentMonth;
        });
        
        const totalHours = monthShifts.reduce((sum, shift) => {
          const start = new Date(`2000-01-01T${shift.startTime}`);
          const end = new Date(`2000-01-01T${shift.endTime}`);
          return sum + (end - start) / (1000 * 60 * 60);
        }, 0);
        
        this.statsData.labels.push(this.getEmployeeName(employeeId));
        this.statsData.shiftsCount.push(monthShifts.length);
        this.statsData.hoursCount.push(totalHours);
      }
      
      this.chart = new Chart(ctx, {
        type: this.chartType,
        data: {
          labels: this.statsData.labels,
          datasets: [
            {
              label: '排班次数',
              data: this.statsData.shiftsCount,
              backgroundColor: 'rgba(54, 162, 235, 0.5)',
              borderColor: 'rgba(54, 162, 235, 1)',
              borderWidth: 1
            },
            {
              label: '总工时(小时)',
              data: this.statsData.hoursCount,
              backgroundColor: 'rgba(75, 192, 192, 0.5)',
              borderColor: 'rgba(75, 192, 192, 1)',
              borderWidth: 1
            }
          ]
        },
        options: {
          responsive: true,
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
      });
    }
  }
}
</script>

<style scoped>
.save-button, .stats-button {
  margin-bottom: 15px;
  padding: 8px 16px;
  color: white;
  border: none;
  border-radius: 4px;
  cursor: pointer;
}

.save-button {
  background-color: #4CAF50;
}

.stats-button {
  background-color: #2196F3;
  margin-left: 10px;
}

.save-button:hover {
  background-color: #45a049;
}

.stats-button:hover {
  background-color: #0b7dda;
}

.chart-container {
  margin-top: 20px;
  padding: 15px;
  background: white;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
}

.dragging {
  opacity: 0.5;
  transform: scale(1.05);
}

.drag-valid {
  border: 2px dashed #4CAF50;
}

.drag-invalid {
  border: 2px dashed #f44336;
}

.schedule-calendar {
  font-family: Arial, sans-serif;
  max-width: 1000px;
  margin: 0 auto;
}

.calendar-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.month-title {
  font-size: 1.5em;
  font-weight: bold;
}

.calendar-grid {
  display: flex;
  flex-direction: column;
}

.calendar-row {
  display: flex;
}

.calendar-day {
  flex: 1;
  border: 1px solid #ddd;
  padding: 5px;
  min-height: 100px;
}

.calendar-day.special-day {
  background-color: #ffeeee;
  border: 2px solid #ff9999;
}

.calendar-day.weekend {
  background-color: #fff0f0;
}

.calendar-day.holiday {
  background-color: #ffdddd;
  font-weight: bold;
}

.conflict-shift {
  background-color: #ffcccc;
  border: 1px dashed #ff0000;
}

.employee-filter {
  margin-bottom: 15px;
}

.day-header {
  font-weight: bold;
  text-align: center;
  margin-bottom: 5px;
}

.shifts-container {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.shift-item {
  background-color: #e6f7ff;
  padding: 2px 5px;
  border-radius: 3px;
  font-size: 0.8em;
  cursor: pointer;
}

.employee-tooltip {
  position: fixed;
  background: white;
  border: 1px solid #ddd;
  border-radius: 4px;
  padding: 10px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
  z-index: 1000;
  min-width: 200px;
}

.employee-tooltip h4 {
  margin: 0 0 8px 0;
  color: #333;
  font-size: 1em;
}

.employee-tooltip p {
  margin: 4px 0;
  color: #666;
  font-size: 0.9em;
}
</style>